package la.iok.hzsvn.lewin.movie.shopmovie.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import la.iok.hzsvn.lewin.movie.core.RoleEnum;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.model.SimpleOrgUnitVo;
import la.iok.hzsvn.lewin.movie.services.MovieServiceInvoker;
import la.iok.hzsvn.lewin.movie.shopmovie.entity.Fees;
import la.iok.hzsvn.lewin.movie.shopmovie.mapper.FeesMapper;
import la.iok.hzsvn.lewin.movie.shopmovie.model.FeesListParam;
import la.iok.hzsvn.lewin.movie.shopmovie.model.FeesParam;
import la.iok.hzsvn.lewin.movie.shopmovie.model.FeesVo;
import la.iok.hzsvn.lewin.mybatis.model.PageParam;
import la.iok.hzsvn.lewin.mybatis.model.PageVo;
import la.iok.hzsvn.lewin.mybatis.model.SortParam;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.collection.IdOperators;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class FeesServiceImpl extends BaseServiceImpl<Fees, FeesMapper, Long> implements FeesService{
    private final MovieServiceInvoker movieServiceInvoker;
    public FeesServiceImpl(FeesMapper mapper, MovieServiceInvoker movieServiceInvoker) {
        super(mapper);
        this.movieServiceInvoker = movieServiceInvoker;
    }

    @Override
    public Long save(Token token, FeesParam param) {
        token.validAnyAuthority(RoleEnum.Manager, RoleEnum.ShopManager);
        validateParam(param);
        validateOrgUnit(token.getOrgUnitId());
        Fees entity = new Fees();
        entity.setAmount(param.getAmount());
        entity.setName(param.getName());
        entity.setOrgUnitId(token.getOrgUnitId());
        insertSelective(entity);
        return entity.getId();
    }

    private void validateOrgUnit(Long orgUnitId) {
        SimpleOrgUnitVo orgUnit = movieServiceInvoker.orgUnitInfo(orgUnitId);
        ErrorCode.ORG_UNIT_NOT_EXIST.assertNotNull(orgUnit, orgUnitId);
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(orgUnit.shopType(),"店铺","操作用户的当前组织必须是店铺类型");
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(orgUnit.normalStatus(),"店铺","店铺已经下线");
    }

    @Override
    public void modify(Token token, Long id, FeesParam param) {
        token.validAnyAuthority(RoleEnum.Manager, RoleEnum.ShopManager);
        validateParam(param);
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(param.getVersion(),"版本","修改时需要带上数据版本");
        Fees entity = select(id);
        ErrorCode.RECORD_NOT_EXIST.assertNotNull(entity, id);
        ErrorCode.ORG_UNIT_ACCESS_DENIED.assertEqual(entity.getOrgUnitId(), token.getOrgUnitId(), entity.getOrgUnitId());
        ErrorCode.RECORD_MODIFIED_ERROR.assertEqual(param.getVersion(), entity.getVersion(),id);
        validateOrgUnit(entity.getOrgUnitId());
        entity.setName(param.getName());
        entity.setAmount(param.getAmount());
        ErrorCode.RECORD_MODIFIED_ERROR.assertEqual(1,mapper.modifyWithVersion(entity),id);
    }

    @Override
    public void delete(Token token, Long id) {
        token.validAnyAuthority(RoleEnum.Manager, RoleEnum.ShopManager);
        Fees entity = select(id);
        ErrorCode.RECORD_NOT_EXIST.assertNotNull(entity, id);
        ErrorCode.ORG_UNIT_ACCESS_DENIED.assertEqual(entity.getOrgUnitId(), token.getOrgUnitId(), entity.getOrgUnitId());
        delete(id);
    }

    @Override
    public PageVo<FeesVo> page(Token token, PageParam pageParam, SortParam sortParam, FeesListParam listParam) {
        if(!token.hasAuthority(RoleEnum.Admin)){
            listParam.setOrgUnitId(token.getOrgUnitId()==null?0:token.getOrgUnitId());
        }
        String orderColumn = sortParam.orderColumn("orgUnitId");
        String order = sortParam.order();
        Page<Fees> page = PageHelper.startPage(pageParam.getPage(), pageParam.getLimit());
        mapper.list(orderColumn, order, listParam);
        Set<Long> orgUnitIds = page.stream().map(Fees::getOrgUnitId).collect(Collectors.toSet());
        List<SimpleOrgUnitVo> orgUnits = movieServiceInvoker.orgUnits(orgUnitIds);
        return page(page, item->{
            FeesVo vo = new FeesVo();
            BeanUtils.copyProperties(item, vo);
            SimpleOrgUnitVo orgUnit = IdOperators.find(orgUnits, item.getOrgUnitId());
            if(orgUnit != null){
                vo.setOrgUnitName(orgUnit.getName());
            }
            return vo;
        });
    }

    private void validateParam(FeesParam param){
        param.setName(ErrorCode.PROPERTY_CHECK_ERROR.assertNotBlank(param.getName(),"名称","名称不能为空"));
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(param.getAmount(),"金额","必须指定金额");
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(param.getAmount() >=0,"金额","金额不能为负数");
    }
}
